package com.just.springbootnosql.service;

import com.just.springbootnosql.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 结构类型	结构存储的值	结构的读写能力
 * String	可以是字符串、整数或者浮点数	对整个字符串或者字符串的其中一部分执行操作；对象和浮点数执行自增(increment)或者自减(decrement)
 * List	一个链表，链表上的每个节点都包含了一个字符串	从链表的两端推入或者弹出元素；根据偏移量对链表进行修剪(trim)；读取单个或者多个元素；根据值来查找或者移除元素
 * Set	包含字符串的无序收集器(unorderedcollection)，并且被包含的每个字符串都是独一无二的、各不相同	添加、获取、移除单个元素；检查一个元素是否存在于某个集合中；计算交集、并集、差集；从集合里卖弄随机获取元素
 * Hash	包含键值对的无序散列表	添加、获取、移除单个键值对；获取所有键值对
 * Zset	字符串成员(member)与浮点数分值(score)之间的有序映射，元素的排列顺序由分值的大小决定	添加、获取、删除单个元素；根据分值范围(range)或者成员来获取元素
 */
@Service
@SuppressWarnings("unchecked")
public class UserServiceImpl implements UserService{
//    @Autowired
//    private JedisCluster jedisCluster;
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public String findRedis() {
        redisTemplate.opsForValue().set("userName","呵呵哒");
        return redisTemplate.opsForValue().get("userName").toString();
    }

    @Override
    public List<User> cacheUsers() {
        List<User> users=new ArrayList<>();
        User user1=new User("1","阿西吧",12);
        User user2=new User("2","阿西九",20);
        User user3=new User("3","阿西十",18);
        users.add(user1);
        users.add(user2);
        users.add(user3);
        redisTemplate.opsForList().leftPush("user.list",user1);
        redisTemplate.opsForList().leftPush("user.list",user2);
        redisTemplate.opsForList().leftPush("user.list",user3);
        //第二种方式
        //redisTemplate.delete("users.list");
        //redisTemplate.opsForList().leftPushAll("user.list",users);
        redisTemplate.expire("user.list",30,TimeUnit.SECONDS);
        return redisTemplate.opsForList().range("user.list",0L,-1L);
    }

    @Override
    public Map<String, User> cacheUserMap() {
        User user=new User("4","测试hash",66);
        User user1=new User("6","测试hash",67);
        User user2=new User("7","测试hash",68);
        User user3=new User("8","测试hash",69);
        Map<String,User> map=new HashMap<>();
        map.put(user1.getId(),user1);
        map.put(user2.getId(),user2);
        map.put(user3.getId(),user3);
        //第一种方式，单个加入
        redisTemplate.opsForHash().put("user.map","4",user);
        //第二种方式，整个map加入
        redisTemplate.opsForHash().putAll("user.map",map);
        return redisTemplate.opsForHash().entries("user.map");
    }

    @Override
    public User findUser(String id) {
        return (User) redisTemplate.opsForHash().get("user.map",id);
    }

    @Override
    public Set<User> cacheUserSet() {
        Set<User> userSet=new HashSet<>();
        User user1=new User("10","测试set",20);
        User user2=new User("11","测试set",21);
        User user3=new User("12","测试set",22);
        userSet.add(user1);
        userSet.add(user2);
        userSet.add(user3);
        //只能一个一个放进去。。。
        redisTemplate.opsForSet().add("user.set",user1,user2,user3);
        return redisTemplate.opsForSet().members("user.set");
    }

    /**
     * zSet:字符串成员(member)与浮点数分值(score)之间的有序映射，元素的排列顺序由分值的大小决定
     */
    @Override
    public Set<User> cacheUserZSet() {
        User user=new User("20","测试zset",13);
        User user1=new User("21","测试zset",14);
        User user2=new User("22","测试zset",15);
        User user3=new User("23","测试zset",16);

        redisTemplate.opsForZSet().add("user.zset",user,1.0);
        ZSetOperations.TypedTuple<Object> typedTuple1=new DefaultTypedTuple<>(user1,Double.valueOf(user1.getId()));
        ZSetOperations.TypedTuple<Object> typedTuple2=new DefaultTypedTuple<>(user2,Double.valueOf(user2.getId()));
        ZSetOperations.TypedTuple<Object> typedTuple3=new DefaultTypedTuple<>(user3,Double.valueOf(user3.getId()));
        Set<ZSetOperations.TypedTuple<Object>> tuples=new HashSet<>();
        tuples.add(typedTuple1);
        tuples.add(typedTuple2);
        tuples.add(typedTuple3);
        redisTemplate.opsForZSet().add("user.zset",tuples);
        return redisTemplate.opsForZSet().range("user.zset",0,-1);
    }
}
